#include "server.h"

extern MYSQL* mySql;

int Register(int peerFd) {
    //接收标志位信息确定用户是要登录还是注册
    int flag;
    int userId = -1;
    int ret = recv(peerFd, &flag, sizeof(int), MSG_WAITALL);
    if(ret < 0) {
        perror("recv");
        return -1;
    } else if(ret == 0) {
        return -1;
    }
    //根据用户提供的数字判断是登录还是注册
    Train_t train;
    if(flag == 0) {
        do{
            //如果要注册，先接收用户提供的用户名
            memset(&train, 0, sizeof(train));
            int ret = recv(peerFd, &train.lenth, sizeof(int), MSG_WAITALL);
            if(ret < 0) {
                perror("recv");
                return -1;
            } else if(ret == 0) {
                return -1;
            }
            ret = recv(peerFd, train.buf, train.lenth, MSG_WAITALL);
            if(ret < 0) {
                perror("recv");
                return -1;
            } else if(ret == 0) {
                return -1;
            }
            //在数据库中查询该用户名，若数据库有重复的用户名，发送标志位提示重新输入
            //否则发送标志位提示继续输入密码
            char querySentence[2048] = {0};
            sprintf(querySentence, "select count(id) from user where username = '%s'", train.buf);
            ret = mysql_query(mySql, querySentence);
            if(ret != 0) {
                printf("query error: %s\n", mysql_error(mySql));
                return -1;
            }
            MYSQL_RES* result = mysql_store_result(mySql);
            if(result == NULL) {
                printf("query error: %s\n", mysql_error(mySql));
                return -1;
            }
            MYSQL_ROW row = mysql_fetch_row(result);
            if(strcmp(row[0], "0") == 0) {
                flag = 0;
            } else {
                flag = 1;
            }
            sendn(peerFd, &flag, sizeof(int));
            mysql_free_result(result);
        } while(flag == 1);
        //将用户名写入缓冲区，再接收用户提供的密码
        char username[1024] = {0};
        strcpy(username, train.buf);
        memset(&train, 0, sizeof(train));
        int ret = recv(peerFd, &train.lenth, sizeof(int), MSG_WAITALL);
        if(ret < 0) {
            perror("recv");
            return -1;
        } else if(ret == 0) {
            return -1;
        }
        ret = recv(peerFd, train.buf, train.lenth, MSG_WAITALL);
        if(ret < 0) {
            perror("recv");
            return -1;
        } else if(ret == 0) {
            return -1;
        }
        //生成盐值，并对用户密码加密，并保存到缓冲区
        char salt[SALT_SIZE + 1] = {0};
        char cryptpasswd[1024] = {0};
        GenerateSalt(salt);
        strcpy(cryptpasswd, crypt(train.buf, salt));
        //向数据库写入用户信息
        char querySentence[2048] = {0};
        sprintf(querySentence, 
                "insert into user (username, salt, cryptpasswd, pwd) values ('%s', '%s', '%s', '~')", 
                username, salt, cryptpasswd);
        ret = mysql_query(mySql, querySentence);
        if(ret != 0) {
            printf("query error: %s\n", mysql_error(mySql));
            return -1;
        }
        //获取用户id
        memset(querySentence, 0, sizeof(querySentence));
        sprintf(querySentence, "select id from user where username = '%s'", username);
        ret = mysql_query(mySql, querySentence);
        if(ret != 0) {
            printf("query error: %s\n", mysql_error(mySql));
            return -1;
        }
        MYSQL_RES* result = mysql_store_result(mySql);
        if(result == NULL) {
            printf("query error: %s\n", mysql_error(mySql));
            return -1;
        }
        MYSQL_ROW row = mysql_fetch_row(result);
        userId = atoi(row[0]);
        mysql_free_result(result);

        //在虚拟文件系统中为新用户创建根目录
        memset(querySentence, 0, sizeof(querySentence));
        sprintf(querySentence, 
                "insert into filesystem (parent_id, filename, owner_id, md5, filesize, type) values (-1, '~', %d, '0', 0, 0)", 
                userId);
        ret = mysql_query(mySql, querySentence);
        if(ret != 0) {
            printf("query error: %s\n", mysql_error(mySql));
            return -1;
        }
    } else {
        do{
            //如果要登录，先接收用户提供的用户名
            memset(&train, 0, sizeof(train));
            int ret = recv(peerFd, &train.lenth, sizeof(int), MSG_WAITALL);
            if(ret < 0) {
                perror("recv");
                return -1;
            } else if(ret == 0) {
                return -1;
            }
            ret = recv(peerFd, train.buf, train.lenth, MSG_WAITALL);
            if(ret < 0) {
                perror("recv");
                return -1;
            } else if(ret == 0) {
                return -1;
            }
            //在数据库中查询该用户名，若数据库没有该用户名，发送标志位提示重新输入
            //否则发送标志位提示继续输入密码
            char querySentence[2048] = {0};
            sprintf(querySentence, "select count(id) from user where username = '%s'", train.buf);
            ret = mysql_query(mySql, querySentence);
            if(ret != 0) {
                printf("query error: %s\n", mysql_error(mySql));
                return -1;
            }
            MYSQL_RES* result = mysql_store_result(mySql);
            if(result == NULL) {
                printf("query error: %s\n", mysql_error(mySql));
                return -1;
            }
            MYSQL_ROW row = mysql_fetch_row(result);
            if(strcmp(row[0], "0") == 0) {
                flag = 0;
            } else {
                flag = 1;
            }
            sendn(peerFd, &flag, sizeof(int));
            mysql_free_result(result);
        } while(flag == 0);
        //将用户名写入缓冲区，再接收用户提供的密码
        char username[1024] = {0};
        strcpy(username, train.buf);
        do{
            memset(&train, 0, sizeof(train));
            int ret = recv(peerFd, &train.lenth, sizeof(int), MSG_WAITALL);
            if(ret < 0) {
                perror("recv");
                return -1;
            } else if(ret == 0) {
                return -1;
            }
            ret = recv(peerFd, train.buf, train.lenth, MSG_WAITALL);
            if(ret < 0) {
                perror("recv");
                return -1;
            } else if(ret == 0) {
                return -1;
            }
            //从数据库中找到用户名对应的盐值和密码的密文
            char cryptpasswd[1024] = {0};
            char querySentence[2048] = {0};
            sprintf(querySentence, "select salt, cryptpasswd, id from user where username = '%s'", username);
            ret = mysql_query(mySql, querySentence);
            if(ret != 0) {
                printf("query error: %s\n", mysql_error(mySql));
                return -1;
            }
            MYSQL_RES* result = mysql_store_result(mySql);
            if(result == NULL) {
                printf("query error: %s\n", mysql_error(mySql));
                return -1;
            }
            MYSQL_ROW row = mysql_fetch_row(result);
            strcpy(cryptpasswd, crypt(train.buf, row[0]));
            //将数据库中的密文和用户发送的密码对应的密文进行比较，如果相同则登录成功，不同则提示用户重新输入
            if(strcmp(cryptpasswd, row[1]) == 0) {
                flag = 0;
                userId = atoi(row[2]);
            } else {
                flag = 1;
            }
            sendn(peerFd, &flag, sizeof(int));
            mysql_free_result(result);
        } while(flag == 1);
    }
    //登陆成功，需要把用户的当前工作目录修改为~
    char querySentence[2048] = {0};
    sprintf(querySentence, "update user set pwd = '~' where id = %d", userId);
    ret = mysql_query(mySql, querySentence);
    if(ret != 0) {
        printf("query error: %s\n", mysql_error(mySql));
        return -1;
    }
    return userId;
}

void GenerateSalt(char* salt) {
    int flag;
    srand(time(NULL));
    for(int i = 0; i < SALT_SIZE; i++) {
        flag = rand() % 3;
        switch(flag) {
        case 0: salt[i] = rand() % 26 + 'a'; break;
        case 1: salt[i] = rand() % 26 + 'A'; break;
        case 2: salt[i] = rand() % 10 + '0'; break;
        }
    }
}
